package cn.touna.jss.modules.custom.batch;

import com.alibaba.fastjson.JSONObject;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 批量工具<br/>
 * 提供：合并csv，切分csv,单次调用,批量调用的功能
 */
public class BatchTool {

    /**
     * 合并csv
     * @param srcDir
     * @param destFile
     * @param containHeader
     * @throws IOException
     */
    public static void mergeFile(File srcDir,File destFile,boolean containHeader) throws IOException {
        if(!srcDir.isDirectory())
            throw new IllegalArgumentException("srcDir不是文件夹|destFile不是文件");
        String header = null;
        BufferedWriter bw = new BufferedWriter(new FileWriter(destFile));

        for (File file : srcDir.listFiles()) {
            try {
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line = null;
                if(containHeader){
                    boolean dirty = false;
                    while((line = br.readLine()) != null){
                        if(!dirty){
                            dirty = true;
                            if(header == null){
                                header = line;
                                bw.append(line).append("\r\n");
                            }
                        }else{
                            bw.append(line).append("\r\n");
                        }
                    }
                }else{
                    while((line = br.readLine()) != null){
                        bw.append(line).append("\r\n");
                    }
                }
                br.close();
                bw.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        bw.close();
    }

    /**
     * 切分csv文件
     * @param srcFile
     * @param targetDir
     * @param rowsInSplit
     * @param containHeader
     * @throws IOException
     */
    public static void splitFile(String srcFile,String targetDir,int rowsInSplit,boolean containHeader) throws IOException {
        File inputFile = new File(srcFile);
        String name = inputFile.getName();
        int ind = name.indexOf('.');
        if(ind > -1)
            name = name.substring(0,ind);
        System.out.println("name: " + name);

        File outputDir = new File(targetDir);
        for (File file : outputDir.listFiles()) {
            file.delete();
        }

        BufferedReader br = new BufferedReader(new FileReader(inputFile));
        String line = null,header = null;
        if(containHeader)
            header = br.readLine();
        int splitIndex = 0;
        int count = 0;

        BufferedWriter bw = getSplitWriter(outputDir,name,splitIndex);
        if(containHeader)
            bw.append(header).append("\r\n");
        while((line = br.readLine()) != null){
            count ++;
            bw.append(line).append("\r\n");
            if(count == rowsInSplit){
                bw.flush();
                bw.close();
                splitIndex ++;
                bw =  getSplitWriter(outputDir,name,splitIndex);
                if(containHeader)
                    bw.append(header).append("\r\n");
                count = 0;
            }
        }
        br.close();
        try{
            bw.flush();
            bw.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    private static BufferedWriter getSplitWriter(File outputDir,String name,int splitIndex) throws IOException {
        String outfilename = outputDir.getPath() + "/" + name + "-"+splitIndex+".csv";
        File file = new File(outfilename);
        System.out.println("outfile: " + file.getPath());
        return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
    }

    /**
     * 批量调用
     * @param formatStr request参数格式化字符串，支持freemarker
     * @param src 来源csv,可以是文件，也可以是文件夹
     * @param destDir 目标文件
     * @param readerConfig csv读取配置
     * @param writerConfig csv写入配置
     * @param threadPool 线程池
     * @param requestProcessor 用于请求的ItemProcessor
     * @throws IOException
     */
    public static void batchRequest(String formatStr,File src,File destDir,
                                    CsvReaderConfig readerConfig,CsvWriterConfig writerConfig,ExecutorService threadPool
            ,ItemProcessor requestProcessor) throws IOException {
        List<File>srcDir = new ArrayList<>();
        if(src.isFile()){
            srcDir.add(src);
        }else if(src.isDirectory()){
            for (File file : src.listFiles()) {
                srcDir.add(file);
            }
        }

        RequestParamProcessor paramProcessor = new RequestParamProcessor();
        paramProcessor.setFormatStr(formatStr);
        List<BatchCounter> counterList = new ArrayList<>();

        int cnt = 0;
        for (File file : srcDir) {
            String name = file.getName();
            int ind = name.indexOf('.');
            if(ind >-1){
                name = name.substring(0,ind);
            }
            String outputFilename = destDir.getPath()+"/"+name + ".csv";
            File outputFile = new File(outputFilename);

            BatchCounter counter = new BatchCounter();
            CsvWriter csvWriter = new CsvWriter(outputFile,writerConfig);
            CsvReader csvReader = new CsvReader(file,readerConfig);
            JSONObject row = null;

            while((row = csvReader.read())!=null){
                cnt ++;
                counter.incrementReadCount();
                RequestThread requestThread = new RequestThread(paramProcessor,requestProcessor,csvWriter,counter);
                requestThread.setRow(row);
                threadPool.execute(requestThread);

                if(cnt % 10 ==0){
//                    System.out.println("activeThreads:" + threadPoolExecutor.getActiveCount());
                }
            }
            counter.setReadComplete(true);
            try {
                TimeUnit.SECONDS.sleep(1);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(counter.checkWriteComplete()){
                System.out.println(counter);
                csvWriter.close();
                counter.setWriteComplete(true);
            }
            counterList.add(counter);
        }

        while(true){
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean b = true;
            for (BatchCounter counter : counterList) {
                b &= counter.isWriteComplete();
                if(!b)
                    break;
            }
            if(b)
                break;
        }
        threadPool.shutdown();
    }

    public static final String url_stg = "http://10.0.4.149:8084/crs/applyCredit";

    public static String doSingleRequest(String url,String request){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> requestEntity = new HttpEntity<>(request, headers);
        return restTemplate.postForObject( url,requestEntity , String.class );
    }


}
